package editorarquivobmg.service;

import editorarquivobmg.codificacao.ICodificacao;
import editorarquivobmg.gui.TelaPrincipal;
import editorarquivobmg.model.BmgFile;
import editorarquivobmg.util.Caracter;
import editorarquivobmg.util.ConversorTexto;
import editorarquivobmg.util.ManipuladorDados;
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
import javax.swing.SpinnerNumberModel;

public class ContadorPixelService {

    private ArrayList<Caracter> pixelCaracteres = null;
    private int qtdPixelLinha = 0;

    public void limparTelaPixels(TelaPrincipal form) {
        pixelCaracteres = null;
        qtdPixelLinha = 0;

        form.getRbDefinirManualmente().setSelected(true);
        form.getRbDefinirAutomaticamente().setEnabled(false);
        form.getRbDefinirManualmente().setEnabled(false);
        form.getSpInformeEndereco().setEnabled(false);
        form.getSpInformeEndereco().setValue(0);
        form.getTxtDefinirManualmente().setEnabled(false);
        form.getLblInformeEndereco().setEnabled(false);
        form.getTxtDefinirManualmente().setText("");
        form.getTxtPixels().setText("");
        form.getLblNumPixelLinha().setText("--");
        form.getLblAviso().setText("--");
    }

    public void instanciarArquivoDePixels(TelaPrincipal form, BmgFile bmgFilePrincipal, ICodificacao codificacao, ManipuladorArquivoService manipuladorArquivo) {
        File arquivo;
        try {
            if (bmgFilePrincipal != null) {
                arquivo = manipuladorArquivo.abrirArquivoPixels(form);
                pixelCaracteres = lerArquivoPixels(arquivo, codificacao);
                form.getSpInformeEndereco().setModel(new SpinnerNumberModel(0, 0, bmgFilePrincipal.getTamanhoPonteiro() - 2, 1));
                form.getTxtDefinirManualmente().setEnabled(true);
                form.getSpInformeEndereco().setEnabled(false);
                form.getRbDefinirAutomaticamente().setEnabled(true);
                form.getRbDefinirManualmente().setEnabled(true);
                form.getLblInformeEndereco().setEnabled(false);
            }
        } catch (Exception ex) {
            System.err.println(ex.getMessage());
        }
    }

    private ArrayList<Caracter> lerArquivoPixels(File arquivo, ICodificacao codificacao) throws Exception {
        String textoOriginal;
        ArrayList<Caracter> caracters = new ArrayList<Caracter>();
        int qtdPixel, numeroCodigos;
        Scanner sc = new Scanner(arquivo);
        numeroCodigos = sc.nextInt();
        for (int i = 0; i < numeroCodigos; i++) {
            textoOriginal = sc.next();
            qtdPixel = sc.nextInt();
            Caracter caractere = new Caracter(qtdPixel, new String(ManipuladorDados.hexStringToByteArray(textoOriginal), codificacao.getCodificacao()));
            caracters.add(caractere);
        }
        return caracters;
    }

    public void preencherTelaPixels(TelaPrincipal form, ConversorTexto parser, BmgFile bmgFilePrincipal) {
        if (bmgFilePrincipal != null) {
            if (pixelCaracteres != null) {
                int length;
                boolean flag = false;
                String texto = form.getTxtMessage().getText(), temp;
                StringTokenizer st = new StringTokenizer(texto, "\n");
                form.getLblNumPixelLinha().setText(qtdPixelLinha + "");
                form.getTxtPixels().setContentType("text/html");
                temp = "<html>\n"
                        + "    <body>\n"
                        + "        <table border = 0 width = 100% cellspacing = 0>\n";
                while (st.hasMoreTokens()) {
                    String line = st.nextToken();
                    if (parser != null) {
                        length = contadorPixelLinha(line, pixelCaracteres, parser);
                    } else {
                        length = contadorPixelLinha(line, pixelCaracteres);
                    }
                    if (length > qtdPixelLinha) {
                        temp += "            <tr height = 5>\n"
                                + "                <td>\n"
                                + "                    <font face = \"Courier New\" color = red size = 3>\n"
                                + "                        <b>" + line + "</b>\n"
                                + "                    </font>\n"
                                + "                </td>\n"
                                + "                <td align = right>\n"
                                + "                    <font face = \"Courier New\" color = red size = 4>\n"
                                + "                        <b>" + length + " pixels</b>\n"
                                + "                    </font>\n"
                                + "                </td>\n"
                                + "            </tr>\n";
                        flag = true;
                    } else {
                        temp += "            <tr height = 5>\n"
                                + "                <td>\n"
                                + "                    <font face = \"Courier New\" size=3>" + line + "\n"
                                + "                    </font>\n"
                                + "                </td>\n"
                                + "                <td align = right>\n"
                                + "                    <font face = \"Courier New\" size=4>\n"
                                + "                        <b>" + length + " pixels</b>\n"
                                + "                    </font>\n"
                                + "                </td>\n"
                                + "            </tr>\n";
                    }
                }
                temp += "        </table>\n"
                        + "    </body>\n"
                        + "</html>";
                form.getTxtPixels().setText(temp);
                if (flag) {
                    form.getLblAviso().setText("Verificar Linha!");
                } else {
                    form.getLblAviso().setText("--");
                }
            }
        }
    }

    private int contadorPixelLinha(String inputString, ArrayList<Caracter> caracters, ConversorTexto parser) {
        int tamanhoModificado, diferenca, tamanhoAuxiliar, cont = 0;
        String retVal = inputString;
        tamanhoAuxiliar = retVal.length();
        for (int i = 0; i < parser.getMapeamentos().size(); i++) {
            retVal = retVal.replace(parser.getMapeamentos().get(i).getTextoSubstituicao(), "");
            tamanhoModificado = retVal.length();
            diferenca = tamanhoAuxiliar - tamanhoModificado;
            cont += (diferenca / parser.getMapeamentos().get(i).getTextoSubstituicao().length()) * parser.getMapeamentos().get(i).getQuantidadetPixels();
            tamanhoAuxiliar = tamanhoAuxiliar - diferenca;
        }

        for (int j = 0; j < caracters.size(); j++) {
            retVal = retVal.replace(caracters.get(j).geCaractereCodificado(), "");
            tamanhoModificado = retVal.length();
            diferenca = tamanhoAuxiliar - tamanhoModificado;
            cont += diferenca * caracters.get(j).getQtdPixels();
            tamanhoAuxiliar = tamanhoAuxiliar - diferenca;
        }
        return cont - 1;
    }

    private int contadorPixelLinha(String inputString, ArrayList<Caracter> caracters) {
        int tamanhoModificado, diferenca, tamanhoAuxiliar, cont = 0;
        String retVal = inputString;
        tamanhoAuxiliar = retVal.length();
        for (int j = 0; j < caracters.size(); j++) {
            retVal = retVal.replace(caracters.get(j).geCaractereCodificado(), "");
            tamanhoModificado = retVal.length();
            diferenca = tamanhoAuxiliar - tamanhoModificado;
            cont += diferenca * caracters.get(j).getQtdPixels();
            tamanhoAuxiliar = tamanhoAuxiliar - diferenca;
        }
        return cont - 1;
    }

    public void setQtdPixelLinha(int qtdPixelLinha) {
        this.qtdPixelLinha = qtdPixelLinha;
    }
}
